import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtCharts

Rectangle {
    Layout.fillWidth: true
    Layout.fillHeight: true

    ColumnLayout {
        anchors.fill: parent

        ChartView {
            id: chartView
            title: "折线图示例"
            titleFont.bold: true
            titleFont.pointSize: 14

            Layout.fillWidth: true
            Layout.fillHeight: true
            antialiasing: true

            ValueAxis {
                id: axis_x
                min: 0
                max: 10
                tickCount: 11
            }

            ValueAxis {
                id: axis_y
                min: 0
                max: 10
                tickCount: 11
            }

            LineSeries {
                id: series
                name: "line"

                color: "#1296FF"
                width: 3
                bestFitLineColor : "#00FF00"
                bestFitLineVisible : true

                // 设置点是否可见
                pointsVisible : true

                // 设置点标签是否可见
                pointLabelsVisible : true

                // 设置点标签文本颜色
                pointLabelsColor: "#FF0000"

                // 设置点标签字体
                pointLabelsFont.bold: true
                pointLabelsFont.pointSize: 12
                pointLabelsFont.family: "Courier"

                // 设置点标签显示格式
                // 具体格式可能受Qt版本或平台影响
                // 如果数据太多，会影响性能
                // 格式标签限制：不支持更复杂的运算或格式化指令，如果是小数，可能需要对点数据预处理
                pointLabelsFormat : "(@xPoint,@yPoint)"

                // 控制当点标签超出绘图区域时是否被裁剪，默认为true
                // 设为false可允许标签显示在绘图区域之外，但需要注意可能布局重叠。
                pointLabelsClipping : true

                axisX: axis_x
                axisY: axis_y

                onClicked: function(point){
                    console.log("onClicked: " + Math.round(point.x) + ", " + Math.round(point.y));
                }
            }

            // 交互：拖拽平移与滚轮缩放
            property real __panStartX: 0
            property real __panStartY: 0
            property real __panStartMinX: 0
            property real __panStartMaxX: 0
            property real __panStartMinY: 0
            property real __panStartMaxY: 0

            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.LeftButton
                hoverEnabled: true
                preventStealing: true

                onPressed: function(mouse) {
                    var pa = chartView.plotArea
                    if (!(mouse.x >= pa.x && mouse.x <= pa.x + pa.width &&
                          mouse.y >= pa.y && mouse.y <= pa.y + pa.height)) {
                        return
                    }
                    chartView.__panStartX = mouse.x
                    chartView.__panStartY = mouse.y
                    chartView.__panStartMinX = axis_x.min
                    chartView.__panStartMaxX = axis_x.max
                    chartView.__panStartMinY = axis_y.min
                    chartView.__panStartMaxY = axis_y.max
                }

                onPositionChanged: function(mouse) {
                    if (!pressed) return
                    var pa = chartView.plotArea
                    if (pa.width <= 0 || pa.height <= 0) return

                    var dx = mouse.x - chartView.__panStartX
                    var dy = mouse.y - chartView.__panStartY

                    var rangeX = chartView.__panStartMaxX - chartView.__panStartMinX
                    var rangeY = chartView.__panStartMaxY - chartView.__panStartMinY

                    // 像素 -> 数值映射（注意Y轴方向）
                    var valueDeltaX = -dx * rangeX / pa.width
                    var valueDeltaY =  dy * rangeY / pa.height

                    axis_x.min = chartView.__panStartMinX + valueDeltaX
                    axis_x.max = chartView.__panStartMaxX + valueDeltaX

                    axis_y.min = chartView.__panStartMinY + valueDeltaY
                    axis_y.max = chartView.__panStartMaxY + valueDeltaY
                }
            }

            WheelHandler {
                // 以光标为中心缩放，支持鼠标与触控板
                acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
                target: chartView
                onWheel: function(event) {
                    var pa = chartView.plotArea
                    var x = event.x
                    var y = event.y
                    if (!(x >= pa.x && x <= pa.x + pa.width &&
                          y >= pa.y && y <= pa.y + pa.height)) {
                        return
                    }

                    // 计算缩放步数（15度/步），向上滚动放大
                    var degrees = event.angleDelta.y / 8.0
                    var steps = degrees / 15.0
                    var factor = Math.pow(1.2, -steps)

                    var minX = axis_x.min
                    var maxX = axis_x.max
                    var minY = axis_y.min
                    var maxY = axis_y.max
                    var rangeX = maxX - minX
                    var rangeY = maxY - minY

                    if (rangeX <= 0 || rangeY <= 0) return

                    var fx = (x - pa.x) / pa.width
                    var fy = (y - pa.y) / pa.height
                    fx = Math.max(0, Math.min(1, fx))
                    fy = Math.max(0, Math.min(1, fy))

                    var newRangeX = rangeX * factor
                    var newRangeY = rangeY * factor

                    // 以光标数值位置为锚点缩放
                    var newMinX = minX + fx * (rangeX - newRangeX)
                    var newMinY = minY + fy * (rangeY - newRangeY)

                    axis_x.min = newMinX
                    axis_x.max = newMinX + newRangeX
                    axis_y.min = newMinY
                    axis_y.max = newMinY + newRangeY

                    event.accepted = true
                }
            }

            // Add data dynamically to the series
            Component.onCompleted: {
                for (var i = 0; i <= 5; i++) {
                    var num = Math.floor((Math.random()*10))
                    series.append(i, num);
                }
            }
        }

        Row {
            Layout.minimumHeight: 50

            Button {
                text: "append"
                width: 100
                height: 25

                onClicked: {
                    var num = Math.floor((Math.random()*10))
                    series.append(series.count, num)
                    axis_x.min++;
                    axis_x.max++;
                }
            }

            Button {
                text: "remove"
                width: 100
                height: 25

                onClicked: {
                    if (series.count > 0) {
                        series.removePoints(series.count-1, 1)
                        axis_x.min--;
                        axis_x.max--;
                    }
                }
            }
        }
    }
}
